package com.ruoyi.baseData.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ruoyi.baseData.domain.Material;
import com.ruoyi.baseData.domain.MaterialType;
import com.ruoyi.baseData.domain.dto.MaterialDto;
import com.ruoyi.baseData.domain.dto.MaterialExcelDto;
import com.ruoyi.baseData.domain.vo.MaterialVo;
import com.ruoyi.baseData.mapper.MaterialMapper;
import com.ruoyi.baseData.mapper.MaterialTypeMapper;
import com.ruoyi.baseData.service.MaterialService;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.core.utils.sql.QueryHelp;
import com.ruoyi.common.security.utils.SecurityUtils;

import com.ruoyi.quality.domain.InspectionTemplateMaterial;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
*
*/
@Service
public class MaterialServiceImpl implements MaterialService {

    @Resource
    MaterialMapper materialMapper;

    @Resource
    MaterialTypeMapper materialTypeMapper;

    @Override
    public Page<MaterialVo> getMaterialByPage(MaterialDto pageEntity) {

        MPJLambdaWrapper<Material> wrapper = new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .selectAs( MaterialType::getName, MaterialVo::getMaterialTypeName )
                .selectAs( InspectionTemplateMaterial::getLowerTolerance, MaterialVo::getLowerTolerance)
                .selectAs( InspectionTemplateMaterial::getUpperTolerance, MaterialVo::getUpperTolerance)
                .selectAs( InspectionTemplateMaterial::getStandardValue, MaterialVo::getStandardValue)
                .selectAs( InspectionTemplateMaterial::getInspectionTemplateId, MaterialVo::getInspectionTemplateId)
                .selectAs(InspectionTemplateMaterial::getInspectionTemplateName, MaterialVo::getInspectionTemplateName)
                .leftJoin(MaterialType.class, on -> on
                        .eq(MaterialType::getId, Material::getMaterialTypeId)
                        .eq(MaterialType::getDelFlag, 0))
                .leftJoin(InspectionTemplateMaterial.class, on -> on
                        .eq(InspectionTemplateMaterial::getMaterialCode, Material::getCode)
                        .eq(InspectionTemplateMaterial::getDelFlag, 0))
//                .likeRight(pageEntity.getCode() != null, Material::getCode, pageEntity.getCode())
//                .like(pageEntity.getName() != null, Material::getName, pageEntity.getName())
//                .like(pageEntity.getMemo() != null, Material::getMemo, pageEntity.getMemo())
                .eq(Material::getDelFlag, 0)
                .orderByDesc(Material::getCreateTime)
                ;
        wrapper = QueryHelp.getPredicateEx(wrapper, Material.class, pageEntity);

                //记的测试阶段
        Page<MaterialVo> userList = materialMapper.selectJoinPage(new Page<>(pageEntity.getCurrentPage(), pageEntity.getPageSize()),   MaterialVo.class, wrapper);
        return userList;
    }

    @Override
    public void addMaterial(MaterialDto materialDto) {
        String userName = SecurityUtils.getUsername();
        MPJLambdaWrapper<Material> wrapper = new MPJLambdaWrapper<Material>()
                .eq(Material::getCode, materialDto.getCode())
                .ne(Material::getDelFlag, 1);;

        Material material = materialMapper.selectOne(wrapper);
        MaterialType materialType = materialTypeMapper.selectById(materialDto.getMaterialTypeId());

        if(null != material) {
            throw new GlobalException("该material已经存在");
        }
        Material test2 = new Material();
        BeanUtils.copyProperties(materialDto, test2, new String[]{"id"});
        test2.setDelFlag(false);
        test2.setCreateBy(userName);
        test2.setCreateTime(new Date());
        materialMapper.insert(test2);
    }

    @Override
    public void updateMaterial(MaterialDto testDto) {
        MPJLambdaWrapper<Material> wrapper = new MPJLambdaWrapper<Material>()
                .eq(Material::getCode, testDto.getCode());
        Material material = materialMapper.selectOne(wrapper);
        if(null == material) {
            throw new GlobalException("该Test不存在");
        }
        BeanUtils.copyProperties(testDto, material);
        material.setCreateBy("admin");
        material.setCreateTime(new Date());
        materialMapper.updateById(material);
    }

    @Override
    public void delMaterial(MaterialDto testDto) {
        Material material = materialMapper.selectById(testDto.getId());
        if(null == material) {
            throw new GlobalException("该Test不存在");
        }
        material.setDelFlag(true);
        materialMapper.updateById(material);
    }

    @Override
    public String uploadMaterial(MultipartFile multipartFile) throws IOException {
        String msg = "";
        if(!multipartFile.getOriginalFilename().contains(".xlsx") && !multipartFile.getOriginalFilename().contains(".xls")) {
            return "文件格式不对";
        }
        EasyExcel.read(multipartFile.getInputStream(), MaterialExcelDto.class, new ReadListener<MaterialExcelDto>(){
            public static final int BATCH_COUNT = 1000;

            private List<MaterialExcelDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

            @Override
            public void invoke(MaterialExcelDto t, AnalysisContext analysisContext) {
                //UNIT如为空，默认取PCS
                if(ObjectUtil.isNull(t.getTestTime())) {
                    t.setTestTime(0);
                }
                if(ObjectUtil.isNull(t.getMaturingTime())) {
                    t.setMaturingTime(0);
                }
//                    t.setUnit("PCS");
////
//                //是否采集SN如为空，默认采集
//                if(ObjectUtil.isNull(t.getGetSn()))
//                    t.setGetSn(true);
//                //是否采集备注如为空，默认不采集
//                if(ObjectUtil.isNull(t.getGetComments()))
//                    t.setGetComments(false);
//                //Warehouse后台可默认写C01
//                if(ObjectUtil.isNull(t.getWarehouse())||  StringUtils.isEmpty(t.getWarehouse()))
//                    t.setWarehouse(DEFAULT_WAREHOUSE);
//                //Plant字段如为空，默认1001
//                if(ObjectUtil.isNull(t.getPlant())||  StringUtils.isEmpty(t.getPlant()))
//                    t.setPlant(DEFAULT_PLANT);
//                //长宽高不为空，自动计算体积，录入后台
//                if(!ObjectUtil.isNull(t.getLength())&& !ObjectUtil.isNull(t.getWidth()) && !ObjectUtil.isNull(t.getHeight()))
//                    t.setVolume(t.getLength()*t.getWidth()*t.getHeight().doubleValue());
//                //如ProductType/ProductFamily为空，根据t_product_type前缀与ProductType/ProductFamily绑定规则，匹配对应的ProductType/ProductFamily值
//                //todo:规则校验
//
//                for(ProductType productType:productTypeList)
//                {
//                    if(t.getMlfb().contains(productType.getMlfbPrefix()))
//                    {
//                        t.setProductType(productType.getProductType());
//                        t.setProductFamily(productType.getProductFamily());
//                        if(productType.getProductType().equals(LICENSE)) {
//                            t.setGetComments(true);
//                        }
//                        break;
//                    }
//                }

                cachedDataList.add(t);
                if (cachedDataList.size() >= BATCH_COUNT) {
                    // 这个是保存数据saveData();
                    // 存储完成清理 list
                    saveData();
                    cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                saveData();
            }

            @Transactional
            private void saveData() {
                //todo: 如果pn重复
                List<String> codes = cachedDataList.stream().map(item -> item.getCode()).distinct().collect(Collectors.toList());
                MPJLambdaWrapper<Material> wrapper = new MPJLambdaWrapper<Material>()
                        .selectAll(Material.class)
                        .eq(Material::getDelFlag, 0)
                        .in(Material::getCode,  codes)
                        .orderByDesc(Material::getCreateTime);
                /**
                 * 存在的物料
                 */
                List<Material> exitMats = materialMapper.selectList(wrapper);
                List<String> existCodes = exitMats.stream().map(item -> item.getCode()).distinct().collect(Collectors.toList());
                List<MaterialExcelDto> materialExcelDtos = cachedDataList.stream().filter(item -> !existCodes.contains(item.getCode()))
                        .collect(Collectors.toList());


                MPJLambdaWrapper<MaterialType> wrapper2 = new MPJLambdaWrapper<MaterialType>()
                        .selectAll(MaterialType.class)
                        .eq(Material::getDelFlag, 0);
                /**
                 * 获取所有的物料类型
                 */
                List<MaterialType> materialTypes = materialTypeMapper.selectList(wrapper2);

                for(MaterialExcelDto materialExcelDto: materialExcelDtos) {
                    Material material = new Material();
                    String materialCode = materialExcelDto.getCode();
                   Optional<MaterialType>  optionalMaterialType = materialTypes.stream().filter(item -> materialCode.startsWith(item.getCode())).findFirst();
                   if(optionalMaterialType.isPresent()) {
                       MaterialType materialType = optionalMaterialType.get();
                       material.setMaterialTypeId(materialType.getId());
                   }


                    BeanUtils.copyProperties(materialExcelDto, material, new String[]{"id"});

                    material.setCreateTime(new Date());
                    material.setCreateBy("System");
                    material.setDelFlag(false);
                    materialMapper.insert(material);
                }
//                List<Material> exitMats = materialRepository.findMaterialsByPnInAndDelete(pns, 0);
//                List<String> existPns = exitMats.stream().map(item -> item.getPn()).distinct().collect(Collectors.toList());
//                List<Material> materials = cachedDataList.stream().filter(item -> !existPns.contains(item.getPn()))
//                        .map(materialMapper::toEntity).collect(Collectors.toList());
//                materialRepository.saveAll(materials);
            }
        }).sheet(0).headRowNumber(1).doRead();
        return msg;

    }
}
